package com.ruoyi.util.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @Author syc
 * @Date Created in 14:48 2022/8/8
 * @Description
 */
public class MainTest {

    /**
     * @Author syc
     * @Date Created in 2022-08-08 15:13:59
     * @Description  1
     */
    public void test1() {
        // 下面这段代码是以反射机制的方式创建对象
        // 通过反射机制, 获取Class, 通过Class来实例化对象
        Class c = null;
        try {
            c = Class.forName("com.ruoyi.util.reflect.User");
            // newInstance() 这个方法会调用user这个类的无参数构造方法,完成对象的创建.
            // 重点是: newInstance()调用的是无参构造,必须保证无参构造是存在的!
            Object obj =  c.newInstance();
            System.out.println(obj.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    public void test2() {
        try {
            StringBuilder s = new StringBuilder();
            Class studentClass = null;
            studentClass = Class.forName("com.ruoyi.util.reflect.User");
            s.append(Modifier.toString(studentClass.getModifiers()) + " class " + studentClass.getSimpleName() + " {\n");// Class类的getName方法
            //获取所有的属性
            Field[] fields = studentClass.getDeclaredFields();
            for (Field f : fields){
                s.append("\t");
                // 获取属性的修饰符列表,返回的修饰符是一个数字，每个数字是修饰符的代号
                // 用Modifier类的toString转换成字符串
                s.append(Modifier.toString(f.getModifiers()));
                if (f.getModifiers() != 0) s.append(" ");
                s.append(f.getType().getSimpleName());// 获取属性的类型
                s.append(" ");
                s.append(f.getName());// 获取属性的名字
                s.append(";\n");
            }
            s.append("}");
            System.out.println(s);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /*
    必须掌握：
        怎么通过反射机制访问一个java对象的属性？
            给属性赋值set
            获取属性的值get
     */
        public  void  test3() {       //不使用反射机制给属性赋值
            User student = new User();
            /**给属性赋值三要素：给s对象的no属性赋值1111
             * 要素1：对象s
             * 要素2：no属性
             * 要素3：1111
             */
            student.setName("王大胆");
            /**读属性值两个要素：获取s对象的no属性的值。
             * 要素1：对象s
             * 要素2：no属性
             */
            System.out.println(student.getName());

            //使用反射机制给属性赋值
        Class userClass = null;
        try {
            userClass = Class.forName("com.ruoyi.util.reflect.User");
            Object obj = userClass.newInstance();// 底层调用无参数构造方法
            // 获取name属性（根据属性的名称来获取Field）
            Field noField = userClass.getDeclaredField("name");
            // 给obj对象(Student对象)的no属性赋值
            noField.setAccessible(true);
            noField.set(obj, "狗蛋");

            // 读取属性的值
            // 两个要素：获取obj对象的no属性的值。
            System.out.println(noField.get(obj));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    public  void test4() {
        try {
            StringBuilder s = new StringBuilder();
            Class user = null;
            user = Class.forName("com.ruoyi.util.reflect.User");
            s.append(Modifier.toString(user.getModifiers()));
            s.append(" class ");
            s.append(user.getSimpleName());
            s.append(" {\n");

            // 获取所有的Method（包括私有的！）
            Method[] methods = user.getDeclaredMethods();
            for (Method m : methods){
                s.append("\t");
                // 获取修饰符列表
                s.append(Modifier.toString(m.getModifiers()));
                s.append(" ");
                // 获取方法的返回值类型
                s.append(m.getReturnType().getSimpleName());
                s.append(" ");
                // 获取方法名
                s.append(m.getName());
                s.append("(");
                // 方法的修饰符列表（一个方法的参数可能会有多个。）
                Class[] parameterTypes = m.getParameterTypes();
                for (int i = 0; i < parameterTypes.length; i++){
                    s.append(parameterTypes[i].getSimpleName());
                    if (i != parameterTypes.length - 1) s.append(", ");
                }
                s.append(") {}\n");
            }
            s.append("}");
            System.out.println(s);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

//    public static void main(String[] args) {
//        MainTest mainTest = new MainTest();
//        try {
//            mainTest.test4();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//



}
